/*
 * @Description: app actions
 * @Author: ZY
 * @Date: 2020-12-23 10:25:37
 * @LastEditors: ycw
 * @LastEditTime: 2022-01-17 11:50:36
 */
import { ActionTree, ActionContext } from 'vuex'
import { RootState, useStore } from '@/store'
import { state, UserState } from './state'
import { Mutations } from './mutations'
import { UserMutationTypes } from './mutation-types'
import { UserActionTypes } from './action-types'
import { loginRequest, userInfoRequest, getRoutersRequest } from '@/apis/user'
import { removeToken, setToken } from '@/utils/cookies'
import { PermissionActionType } from '../permission/action-types'
import router, { resetRouter } from '@/router'
import { RouteRecordRaw } from 'vue-router'

type AugmentedActionContext = {
  commit<K extends keyof Mutations>(
    key: K,
    payload: Parameters<Mutations[K]>[1],
  ): ReturnType<Mutations[K]>
} & Omit<ActionContext<UserState, RootState>, 'commit'>

export interface Actions {
  [UserActionTypes.ACTION_LOGIN](
    { commit }: AugmentedActionContext,
    userInfo: { username: string, password: string }
  ): void
  [UserActionTypes.ACTION_RESET_TOKEN](
    { commit }: AugmentedActionContext
  ): void
  [UserActionTypes.ACTION_GET_USER_INFO](
    { commit }: AugmentedActionContext
  ): void
  [UserActionTypes.ACTION_CHANGE_ROLES](
    { commit }: AugmentedActionContext, role: string
  ): void
  [UserActionTypes.ACTION_GET_USER_ROUTERS](
    { commit }: AugmentedActionContext,
  ): void
  [UserActionTypes.ACTION_LOGIN_OUT](
    { commit }: AugmentedActionContext,
  ): void
}

export const actions: ActionTree<UserState, RootState> & Actions = {
  async [UserActionTypes.ACTION_LOGIN](
    { commit }: AugmentedActionContext,
    userInfo: { username: string, password: string, code: number, uuid: string }
  ): Promise<any> {
    let { username, password, code, uuid } = userInfo
    username = username.trim()
    return new Promise((resolve, reject) => {
      loginRequest({ username, password, code, uuid }).then(async(res) => {
        if (res?.code === 200 && res.data.access_token) {
          setToken(res.data.access_token)
          commit(UserMutationTypes.SET_TOKEN, res.data.access_token)
        }
        resolve(res)
      }).catch((err) => {
        console.log(err)
        reject(err)
      })
    })
  },

  [UserActionTypes.ACTION_RESET_TOKEN](
    { commit }: AugmentedActionContext) {
    removeToken()
    commit(UserMutationTypes.SET_TOKEN, '')
    commit(UserMutationTypes.SET_ROLES, [])
  },

  async [UserActionTypes.ACTION_GET_USER_INFO](
    { commit }: AugmentedActionContext
  ) {
    if (state.token === '') {
      throw Error('token is undefined!')
    }
    await userInfoRequest().then(async(res) => {
      commit(UserMutationTypes.SET_ROLES, res.roles)
      commit(UserMutationTypes.SET_NAME, res.user.name)
      commit(UserMutationTypes.SET_AVATAR, res.user.avatar)
      commit(UserMutationTypes.SET_INTRODUCTION, res.user.introduction)
      commit(UserMutationTypes.SET_EMAIL, res.user.email)
      commit(UserMutationTypes.SET_PREMISSION, res.permissions)
      // const store = useStore()
      // await store.dispatch(UserActionTypes.ACTION_GET_USER_ROUTERS, undefined)
      return res
    })
  },
  //  获取路由信息
  async [UserActionTypes.ACTION_GET_USER_ROUTERS](
    { commit }: AugmentedActionContext
  ) {
    if (state.token === '') {
      throw Error('token is undefined!')
    }
    await getRoutersRequest().then((res) => {
      commit(UserMutationTypes.SET_ROUTERS, res.data)
      state.routers.forEach((item: RouteRecordRaw) => {
        router.addRoute(item)
      })
      console.log('--------------------------router')
      return res
    }).catch(err => {
      console.log(err)
    })
  },

  async [UserActionTypes.ACTION_CHANGE_ROLES](
    { commit }: AugmentedActionContext,
    role: string
  ) {
    const token = role + '-token'
    const store = useStore()
    commit(UserMutationTypes.SET_TOKEN, token)
    setToken(token)
    await store.dispatch(UserActionTypes.ACTION_GET_USER_INFO, undefined)
    store.dispatch(PermissionActionType.ACTION_SET_ROUTES, state.roles)
    store.state.permission.dynamicRoutes.forEach((item: RouteRecordRaw) => {
      router.addRoute(item)
    })
  },

  [UserActionTypes.ACTION_LOGIN_OUT](
    { commit }: AugmentedActionContext
  ) {
    console.log(commit)
    removeToken()
    commit(UserMutationTypes.SET_TOKEN, '')
    commit(UserMutationTypes.SET_ROLES, [])
    resetRouter()
  }
}
